feat(group-chat): 建立 v2 actor/access 与运行时撤权基础 - #2233
Open
hanzckernel wants to merge 3 commits into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
这个 PR 不是单纯的邀请码、退房和复制按钮改动,而是 Group Chat v2 的第一层安全基础:把房间 actor、capability、邀请准入、REST / Socket.IO 授权和 Agent 运行时撤权统一到一条可持久化、可迁移、可复查的授权链上。
此前房主、成员行、账号可用 Profile、房间 Agent Profile 和 Socket 在线状态分散参与权限判断;请求开始时取得的身份也可能跨越异步操作继续使用。结果是房间读取、实时投递、审批、Agent Bridge 和上下文压缩没有共享同一条权威边界,尤其可能把“账号能使用某个 Agent Profile”误当成“账号能进入包含该 Profile 的房间”。
本 PR 统一以下不变量:
改动
1. 持久化 actor、capability 与访问策略
authenticated_human、local、agent和system统一为稳定 actor 身份。room.read、room.write、room.type、room.manage、agent.invoke、approval.respond;REST、Socket.IO、Agent 与审批运行时共享同一套 typed policy 结果。2. REST、Socket.IO 与账号生命周期使用同一授权边界
Room not found形状,不能枚举私有房间。await后重新读取账号状态、角色、Profile entitlement 和房间 grant,再返回数据或执行 mutation。room.read;读权限被撤销的连接会先退出 Socket.IO room 和 runtime presence,再阻止 message、tool/workspace、stream、reasoning、approval 和 context-status 事件。canManage、canApprove、canLeave;邀请码和 workspace 只对有对应权限的调用方暴露,客户端不再根据 owner/member 状态自行猜测权限。3. 原子邀请码准入与防枚举保护
inviteGeneration和房间授权 revision;旧邀请码与轮换竞态不能留下半写入成员或 actor。4. 服务端权威的加入、复制和退房闭环
DELETE /api/hermes/group-chat/rooms/:roomId/members/me会停用当前 authenticated-human actor、移除 membership、驱逐该用户的实时连接并保留房间本身。ownerAuthUserId,而不是继续保留 owner-only access。退房后,旧 Socket 不能继续发送,且无新邀请码时不能重新进入。5. Auth-disabled 本地身份与第一方传输一致性
6. Agent、审批、Bridge session 与上下文运行时 fencing
agent.invoke同时约束人类触发和 Agent-to-Agent mention;approval.respond独立于room.manage,审批事件只投递给当前仍有响应权限的每个 Socket。7. Forward-only migration 与 SQLite 进程所有权
groupChatIdentityV1migration,通过中央 Hermes schema 初始化执行。closeDb()或 owner 进程退出后由内核释放锁并允许重新获取。为什么改动范围较大
当前 exact head 为
3d2c43e51ccd2e7540486a1c69cc79af9e210343,相对 basebc0f0b41200ae8be118c39b96460f483b5f112ae共 96 files /+11,450 -823:其中生产代码 32 files,测试 61 files,文档/OpenAPI 3 files。这些文件围绕的是同一条授权不变量,而不是互不相关的功能拼盘:
await的旧授权仍可在撤权后提交;因此本 PR 保留为一个 independently safe 的 v2 PR1:拆开会产生可被 REST、Socket 或在途运行绕过的中间状态。
升级与回滚
groupChatIdentityV1是 forward-only schema boundary;数据库完成升级后,不支持直接降级到不理解该 reader epoch 的旧版本。HERMES_WEB_UI_HOME,并将 SQLite 数据库与.group-chat-local-identity-secret一起保存;使用GROUP_CHAT_LOCAL_IDENTITY_SECRET时必须保留与数据库匹配的同一值。Roadmap 与范围边界
本 PR 是 latest-main Group Chat v2 roadmap 的 PR1 — actor/access foundation。它完成身份、准入、统一授权与 public-room Agent/Bridge 生命周期 fencing,但不宣称后续隐私层已经完成:
Related: #2226。该 PR 处理相邻的 mixed-runtime participant 能力;本 PR 不依赖其分支,也不会自动关闭该 issue/PR。
验证
Exact head:
3d2c43e51ccd2e7540486a1c69cc79af9e210343。本地:
npm run harness:check:通过。npm test -- tests/server/group-chat-invite-admission.test.ts tests/server/group-chat-member-sync.test.ts tests/client/group-chat-panel-workspace-source.test.ts tests/client/group-chat-store-workspace.test.ts tests/client/group-chat-api-invite.test.ts:5 files / 68 tests 通过。npm run test:e2e -- tests/e2e/group-chat-room-deeplink.spec.ts:9 tests 通过。npm test -- tests/server/group-chat-*.test.ts --testTimeout=15000:24 files / 250 tests 通过。npm run build:通过。git diff --check:通过。VERDICT: NO BLOCKERS,P0/P1/P2 均为空。GitHub CI(同一 exact head):
harness:check、test:coverage和 production build 全部成功。说明
origin/main干净重放,未包含 donor worktree 中无关的 agent-runner 修改。